package test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import dsa.LinkedList;
import dsa.ListIterator;

public class SaraSchlosserTest {

	public LinkedList list =  new LinkedList();
	public ListIterator itty;
	
	@Before
	public void setUp() throws Exception {
			
									//index
		list.addFirst("john");		//3
		list.addFirst("kate");		//2
		list.addLast("paige");		//4
		list.addLast("lynn");		//5
		list.addLast("bob");		//6
		list.addLast("fred");		//7
		list.addLast("tina");		//8
		list.addLast("sam");		//9
		list.addFirst("allie");		//1
		list.addFirst("tyler");		//0
		
		
	}


	@Test
	public void sizeTest() {
		assertTrue(list.size() == 10);
		assertFalse(list.size() == 0);
		assertFalse(list.size() == 6);
		assertFalse(list.size() == 13);
	}
	
	@Test
	public void getTest() {
		assertTrue(list.get(3).equals("john"));
		assertTrue(list.getLast().equals("sam"));
		assertTrue(list.get(0).equals("tyler"));
		assertTrue(list.getFirst().equals("tyler"));		
	}
	
	@Test
	public void removeTest() {
		assertTrue(list.size() == 10);
		
		assertTrue(list.get(6).equals("bob"));
		assertTrue(list.remove(6).equals("bob"));
		assertTrue(list.get(6).equals("fred"));
		
		assertTrue(list.getFirst().equals("tyler"));
		assertTrue(list.removeFirst().equals("tyler"));
		assertTrue(list.getFirst().equals("allie"));
		
		assertTrue(list.getLast().equals("sam"));
		assertTrue(list.removeLast().equals("sam"));
		assertTrue(list.getLast().equals("tina"));
		
		assertTrue(list.size() == 7);
	}
	
	@Test
	public void indexOfTest(){
		assertTrue(list.indexOf("tyler") == 0 );
		assertTrue(list.get(0).equals("tyler"));
		
		assertTrue(list.indexOf("john") == 3);
		assertTrue(list.get(3).equals("john"));
		
		assertFalse(list.indexOf("sam") == 8);
		assertTrue(list.get(8).equals("tina"));
		
		assertFalse(list.indexOf("kate") == 1);
		assertFalse(list.indexOf("kate") == 3);
		assertTrue(list.indexOf("kate") == 2);
	}
	
	@Test
	public void containsTest(){
		assertTrue(list.contains("lynn") == true);
		assertTrue(list.contains("allie") == true);
		assertTrue(list.contains("tyler") == true);
		
		assertTrue(list.contains(17) == false);
		assertTrue(list.contains("rob") == false);
		
		assertFalse(list.contains("candy") == true);
		assertFalse(list.contains(62) == true);
	}
	
	@Test
	public void cloneTest(){
		LinkedList cloned = new LinkedList();
		cloned = (LinkedList) list.clone();
		
		assertTrue(cloned.size() == 10);
		assertTrue(cloned.get(5).equals(list.get(5)));
		assertTrue(cloned.getLast().equals(list.get(9)));
		assertTrue(cloned.getFirst().equals(list.getFirst()));
		assertTrue(cloned.indexOf("tyler") == (list.indexOf("tyler")));
		assertTrue(cloned.contains("allie") == (list.contains("allie")));
		assertTrue(cloned.remove(6).equals(list.remove(6)));
	}
	
	@Test
	public void setTest(){
		assertTrue(list.size() == 10);
		assertTrue(list.get(7).equals("fred"));
		assertTrue((list.set(7, "lily")).equals("fred"));
		assertTrue(list.size() == 10);
		assertTrue(list.get(7).equals("lily"));
		assertTrue(list.get(4).equals("paige"));
		assertTrue(list.get(6).equals("bob"));
		assertTrue(list.get(8).equals("tina"));
		assertTrue(list.size() == 10);
	}

	@Test
	public void toArrayTest(){
		Object array[] = list.toArray();
		
		assertTrue(array.length == list.size());
		assertTrue(array[3].equals(list.get(3)));
		assertTrue(array[0].equals(list.getFirst()));
		assertTrue(array[9].equals(list.getLast()));
	}
	
	//______________________iterator tests______________________//
	@Test
	public void nextTest(){
		itty = list.listIterator(0);				//TESTING EVERY OBJ IN LIST
		assertEquals(itty.next(),"tyler");				//1
		assertEquals(itty.next(),"allie");				//2
		itty.next();								//jumps to third
		assertEquals(itty.next(),"john");				//3
		itty.next(); itty.next();					//jumps to sixth
		assertEquals(itty.next(),"bob");				//7
		itty.next(); itty.next(); itty.next();		//jumps to ninth
		assertEquals(itty.next(), null);				//jumps to null
	}
	
	@Test
	public void hasNextTest(){
		itty = list.listIterator(0);
			assertEquals(itty.hasPrevious(), false);
		for (int i = 0 ; i < list.size() ; i ++){			//testing objects 0-9
			assertEquals(itty.hasNext(), true);
			itty.next();	
		}
		itty.next();	
		assertEquals(itty.hasNext(), false);			//testing object after index 9 is null		
	}
	
	@Test
	public void previousTest(){
		itty = list.listIterator(list.size());				//TESTING EVERY OBJ IN LIST
		assertEquals(itty.previous(),"sam");				//9
		assertEquals(itty.previous(),"tina");				//8
		itty.previous();										//jumps to seventh
		assertEquals(itty.previous(),"bob");				//6
		itty.previous(); itty.previous();						//jumps to fourth
		assertEquals(itty.previous(),"john");				//3
		itty.previous(); itty.previous(); itty.previous();		//jumps to first
		assertEquals(itty.previous(), null);				//jumps to null
		
	}
	
	@Test
	public void haspreviousTest(){
		itty = list.listIterator(list.size());
		assertEquals(itty.hasNext(), false);
		for (int i = 0 ; i < list.size() ; i ++){			//testing objects 9 - 0
			assertEquals(itty.hasPrevious(), true);
			itty.previous();	
		}
		itty.previous();	
		assertEquals(itty.hasPrevious(), false);			//testing object after index 0 is null
	}
	
	@Test
	public void indexTest(){
		itty = list.listIterator(0);
		for (int i = 0 ; i < list.size() ; i ++){
			assertEquals(itty.nextIndex(), i);
			itty.next();	
		}
		for (int i = list.size()-1 ; i >= 0 ; i --){
			assertEquals(itty.previousIndex(), i );
			itty.previous();	
		}
		
		itty.next();
		assertEquals(itty.nextIndex(), 1);
		itty.next();
		assertEquals(itty.nextIndex(), 2);
		itty.next(); itty.previous();
		assertEquals(itty.nextIndex(), 2);
		itty.previous();
		assertEquals(itty.nextIndex(), 1);
		itty.next();
		assertEquals(itty.nextIndex(), 2);
	}

	@Test
	public void addRemoveTest(){
		itty = list.listIterator(0);
		itty.next();
		assertEquals(itty.next(), "allie");		//index 1, second object
		assertEquals(itty.next(), "kate");		//index 2, third object
		itty.previous();
		itty.remove();			//remove allie
		assertEquals(itty.next(), "kate");		//new second object
		itty.previous(); itty.previous();				//start from index 0
		assertEquals(itty.next(), "tyler");				//check index 0
		assertEquals(itty.next(), "kate");				//check index 1
		assertEquals(itty.next(), "john");				//check index 2
		itty.remove();			//remove john
		assertEquals(itty.next(), "paige");			//next
		assertEquals(itty.previous(), "paige");		//previous (same)
		assertEquals(itty.previous(), "kate");		//previous
	}
	
	@Test
	public void setIteratorTest(){
		itty = list.listIterator(8);
		itty.previous();
		itty.previous();
		itty.next();		//curr at "bob"
		itty.set("rob");		//change bob to rob
		itty.previous();
		assertEquals(itty.previous(), "lynn");
		itty.next();
		assertEquals(itty.next(), "rob");
		assertEquals(itty.next(), "fred");
	}
	
	@After
	public void tearDown() throws Exception {
	}
}
